/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "spatial_algorithm_handle.h"

#include <thread>
#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <dirent.h>
#include <elf.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include "constants.h"
#include "securec.h"
#include "spatial_awareness_common.h"

namespace OHOS {
namespace Msdp {
bool SpatialAlgorithmHandle::Init()
{
    int sleepTime = 3000;
    std::vector<std::string> files;
    std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
    GetLiblaryFiles(ALGORITHM_COMMON_PATH, files);
    for (auto file : files) {
        std::regex r("[[:alpha:]]*msdp.*algorithm.*so[[:alpha:]]*");
        std::smatch result;
        RegexSearch(file, r, result);
    }
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s size = %{public}d", __func__, files.size());
    return true;
}

int SpatialAlgorithmHandle::GetServiceDll(const AlgorithmType &type, std::string &dlname)
{
    auto iter = mServiceDllMap_.find(type);
    if (iter == mServiceDllMap_.end()) {
        return SPATIALMANAGER_FAILED;
    }
    dlname = iter->second;
    return SPATIALMANAGER_OK;
}

int SpatialAlgorithmHandle::CheckAndEnforceService(const AlgorithmType &type, bool bCreate)
{
    uint32_t typeValue = static_cast<uint32_t>(type);
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s name = %{public}d", __func__, typeValue);
    std::string dlname;
    if (GetServiceDll(type, dlname) < SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}d does not support", typeValue);
        return SPATIALMANAGER_FAILED;
    }
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s dlname = %{public}s", __func__, dlname.c_str());

    std::unique_lock<std::mutex> lock(mMutex_);
    if (type == AlgorithmType::DIRECTION) {
        return LoadDirectionLib(dlname, bCreate);
    }
    if (type == AlgorithmType::DISTANCE) {
        return LoadDistanceLib(dlname, bCreate);
    }
    if (type == AlgorithmType::ANGLE) {
        return LoadAngleLib(dlname, bCreate);
    }
    if (type == AlgorithmType::INNEROUTER) {
        return LoadInnerouterLib(dlname, bCreate);
    }
    if (type == AlgorithmType::EXIST) {
        return LoadExistLib(dlname, bCreate);
    }
    if (type == AlgorithmType::COMMON) {
        return LoadCommonLib(dlname, bCreate);
    }
    return SPATIALMANAGER_FAILED;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetAlgoInstance(const AlgorithmType &type)
{
    uint32_t typeValue = static_cast<uint32_t>(type);
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s name = %{public}d", __func__, typeValue);
    std::string dlname;
    if (GetServiceDll(type, dlname) < SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}d does not support", typeValue);
        return nullptr;
    }
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s dlname = %{public}s", __func__, dlname.c_str());

    if (type == AlgorithmType::DIRECTION) {
        return GetDirectionInst();
    }
    if (type == AlgorithmType::DISTANCE) {
        return GetDistanceInst();
    }
    if (type == AlgorithmType::ANGLE) {
        return GetAngleInst();
    }
    if (type == AlgorithmType::INNEROUTER) {
        return GetInnerouterInst();
    }
    if (type == AlgorithmType::EXIST) {
        return GetExistInst();
    }
    if (type == AlgorithmType::COMMON) {
        return GetCommonInst();
    }
    return nullptr;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetCommonInst()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mCommonAlgo_.handle == nullptr) {
        return nullptr;
    }
    if (mCommonAlgo_.pAlgorithm == nullptr) {
        std::unique_lock<std::mutex> lock(mMutex_);
        SPATIAL_LOGI(MODULE_SERVICE, "%{public}s mCommonAlgo_", __func__);
        if (mCommonAlgo_.pAlgorithm == nullptr) {
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s Get mAlgorithm.pAlgorithm", __func__);
            mCommonAlgo_.pAlgorithm = mCommonAlgo_.create();
        }
    }
    return mCommonAlgo_.pAlgorithm;
}

int32_t SpatialAlgorithmHandle::LoadCommonLib(const std::string &dlname, bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mCommonAlgo_.handle != nullptr) {
        return SPATIALMANAGER_OK;
    }
    mCommonAlgo_.handle = dlopen(dlname.c_str(), RTLD_LAZY);
    if (mCommonAlgo_.handle == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
        return SPATIALMANAGER_FAILED;
    }

    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
    mCommonAlgo_.create = (MsdpAlgorithmInterface *(*)()) dlsym(mCommonAlgo_.handle, "Create");
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
    mCommonAlgo_.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(mCommonAlgo_.handle, "Destroy");
    if (mCommonAlgo_.create == nullptr || mCommonAlgo_.destroy == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", dlname.c_str());
        dlclose(mCommonAlgo_.handle);
        mCommonAlgo_.Clear();
        bCreate = false;
        return SPATIALMANAGER_FAILED;
    }

    if (bCreate) {
        mCommonAlgo_.pAlgorithm = mCommonAlgo_.create();
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::UnloadCommonLib(bool bPreLoad)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mCommonAlgo_.handle == nullptr) {
        return SPATIALMANAGER_FAILED;
    }

    if (mCommonAlgo_.pAlgorithm != nullptr) {
        mCommonAlgo_.destroy(mCommonAlgo_.pAlgorithm);
        mCommonAlgo_.pAlgorithm = nullptr;
    }

    if (!bPreLoad) {
        dlclose(mCommonAlgo_.handle);
        mCommonAlgo_.Clear();
    }
    return SPATIALMANAGER_OK;
}

int32_t SpatialAlgorithmHandle::LoadDirectionLib(const std::string &dlname, bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mDirectionAlgorithm_.handle != nullptr) {
        return SPATIALMANAGER_OK;
    }
    mDirectionAlgorithm_.handle = dlopen(dlname.c_str(), RTLD_LAZY);
    if (mDirectionAlgorithm_.handle == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
        return SPATIALMANAGER_FAILED;
    }

    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
    mDirectionAlgorithm_.create = (MsdpAlgorithmInterface *(*)()) dlsym(mDirectionAlgorithm_.handle, "Create");
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
    mDirectionAlgorithm_.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(mDirectionAlgorithm_.handle, "Destroy");
    if (mDirectionAlgorithm_.create == nullptr || mDirectionAlgorithm_.destroy == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", dlname.c_str());
        dlclose(mDirectionAlgorithm_.handle);
        mDirectionAlgorithm_.Clear();
        bCreate = false;
        return SPATIALMANAGER_FAILED;
    }

    if (bCreate) {
        mDirectionAlgorithm_.pAlgorithm = mDirectionAlgorithm_.create();
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::UnloadDirectionLib(bool bPreLoad)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mDirectionAlgorithm_.handle == nullptr) {
        return SPATIALMANAGER_FAILED;
    }

    if (mDirectionAlgorithm_.pAlgorithm != nullptr) {
        mDirectionAlgorithm_.destroy(mDirectionAlgorithm_.pAlgorithm);
        mDirectionAlgorithm_.pAlgorithm = nullptr;
    }

    if (!bPreLoad) {
        dlclose(mDirectionAlgorithm_.handle);
        mDirectionAlgorithm_.Clear();
    }
    return SPATIALMANAGER_OK;
}

int32_t SpatialAlgorithmHandle::LoadDistanceLib(const std::string &dlname, bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mDistanceAlgorithm_.handle != nullptr) {
        return SPATIALMANAGER_OK;
    }
    mDistanceAlgorithm_.handle = dlopen(dlname.c_str(), RTLD_LAZY);
    if (mDistanceAlgorithm_.handle == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
        return SPATIALMANAGER_FAILED;
    }

    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
    mDistanceAlgorithm_.create = (MsdpAlgorithmInterface *(*)()) dlsym(mDistanceAlgorithm_.handle, "Create");
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
    mDistanceAlgorithm_.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(mDistanceAlgorithm_.handle, "Destroy");
    if (mDistanceAlgorithm_.create == nullptr || mDistanceAlgorithm_.destroy == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", dlname.c_str());
        dlclose(mDistanceAlgorithm_.handle);
        mDistanceAlgorithm_.Clear();
        bCreate = false;
        return SPATIALMANAGER_FAILED;
    }

    if (bCreate) {
        mDistanceAlgorithm_.pAlgorithm = mDistanceAlgorithm_.create();
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::UnloadDistanceLib(bool bPreLoad)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mDistanceAlgorithm_.handle == nullptr) {
        return SPATIALMANAGER_FAILED;
    }

    if (mDistanceAlgorithm_.pAlgorithm != nullptr) {
        mDistanceAlgorithm_.destroy(mDistanceAlgorithm_.pAlgorithm);
        mDistanceAlgorithm_.pAlgorithm = nullptr;
    }

    if (!bPreLoad) {
        dlclose(mDistanceAlgorithm_.handle);
        mDistanceAlgorithm_.Clear();
    }
    return SPATIALMANAGER_OK;
}

int32_t SpatialAlgorithmHandle::LoadAngleLib(const std::string &dlname, bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mAngleAlgorithm_.handle != nullptr) {
        return SPATIALMANAGER_OK;
    }
    mAngleAlgorithm_.handle = dlopen(dlname.c_str(), RTLD_LAZY);
    if (mAngleAlgorithm_.handle == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
        return SPATIALMANAGER_FAILED;
    }

    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
    mAngleAlgorithm_.create = (MsdpAlgorithmInterface *(*)()) dlsym(mAngleAlgorithm_.handle, "Create");
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
    mAngleAlgorithm_.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(mAngleAlgorithm_.handle, "Destroy");
    if (mAngleAlgorithm_.create == nullptr || mAngleAlgorithm_.destroy == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", dlname.c_str());
        dlclose(mAngleAlgorithm_.handle);
        mAngleAlgorithm_.Clear();
        bCreate = false;
        return SPATIALMANAGER_FAILED;
    }

    if (bCreate) {
        mAngleAlgorithm_.pAlgorithm = mAngleAlgorithm_.create();
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::UnloadAngleLib(bool bPreLoad)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mAngleAlgorithm_.handle == nullptr) {
        return SPATIALMANAGER_FAILED;
    }

    if (mAngleAlgorithm_.pAlgorithm != nullptr) {
        mAngleAlgorithm_.destroy(mAngleAlgorithm_.pAlgorithm);
        mAngleAlgorithm_.pAlgorithm = nullptr;
    }

    if (!bPreLoad) {
        dlclose(mAngleAlgorithm_.handle);
        mAngleAlgorithm_.Clear();
    }
    return SPATIALMANAGER_OK;
}

int32_t SpatialAlgorithmHandle::LoadInnerouterLib(const std::string &dlname, bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mIoAlgorithm_.handle != nullptr) {
        return SPATIALMANAGER_OK;
    }
    mIoAlgorithm_.handle = dlopen(dlname.c_str(), RTLD_LAZY);
    if (mIoAlgorithm_.handle == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
        return SPATIALMANAGER_FAILED;
    }

    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
    mIoAlgorithm_.create = (MsdpAlgorithmInterface *(*)()) dlsym(mIoAlgorithm_.handle, "Create");
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
    mIoAlgorithm_.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(mIoAlgorithm_.handle, "Destroy");
    if (mIoAlgorithm_.create == nullptr || mIoAlgorithm_.destroy == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", dlname.c_str());
        dlclose(mIoAlgorithm_.handle);
        mIoAlgorithm_.Clear();
        bCreate = false;
        return SPATIALMANAGER_FAILED;
    }

    if (bCreate) {
        mIoAlgorithm_.pAlgorithm = mIoAlgorithm_.create();
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::UnloadInnerouterLib(bool bPreLoad)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mIoAlgorithm_.handle == nullptr) {
        return SPATIALMANAGER_FAILED;
    }

    if (mIoAlgorithm_.pAlgorithm != nullptr) {
        mIoAlgorithm_.destroy(mIoAlgorithm_.pAlgorithm);
        mIoAlgorithm_.pAlgorithm = nullptr;
    }

    if (!bPreLoad) {
        dlclose(mIoAlgorithm_.handle);
        mIoAlgorithm_.Clear();
    }
    return SPATIALMANAGER_OK;
}

int32_t SpatialAlgorithmHandle::LoadExistLib(const std::string &dlname, bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mExistAlgorithm_.handle != nullptr) {
        return SPATIALMANAGER_OK;
    }
    mExistAlgorithm_.handle = dlopen(dlname.c_str(), RTLD_LAZY);
    if (mExistAlgorithm_.handle == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
        return SPATIALMANAGER_FAILED;
    }

    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
    mExistAlgorithm_.create = (MsdpAlgorithmInterface *(*)()) dlsym(mExistAlgorithm_.handle, "Create");
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
    mExistAlgorithm_.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(mExistAlgorithm_.handle, "Destroy");
    if (mExistAlgorithm_.create == nullptr || mExistAlgorithm_.destroy == nullptr) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", dlname.c_str());
        dlclose(mExistAlgorithm_.handle);
        mExistAlgorithm_.Clear();
        bCreate = false;
        return SPATIALMANAGER_FAILED;
    }

    if (bCreate) {
        mExistAlgorithm_.pAlgorithm = mExistAlgorithm_.create();
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::UnloadExistLib(bool bPreLoad)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mExistAlgorithm_.handle == nullptr) {
        return SPATIALMANAGER_FAILED;
    }

    if (mExistAlgorithm_.pAlgorithm != nullptr) {
        mExistAlgorithm_.destroy(mExistAlgorithm_.pAlgorithm);
        mExistAlgorithm_.pAlgorithm = nullptr;
    }

    if (!bPreLoad) {
        dlclose(mExistAlgorithm_.handle);
        mExistAlgorithm_.Clear();
    }
    return SPATIALMANAGER_OK;
}

int32_t SpatialAlgorithmHandle::LoadAllLib(bool bCreate)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (algorithmLibList_.empty()) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s algorithmLibList_ is nullptr", __func__);
        return false;
    }
    for (auto iter : algorithmLibList_) {
        SPATIAL_LOGI(MODULE_SERVICE, "%{public}s algorithm = %{public}s", __func__, iter.c_str());
        CommonAlgorithmHandle commonHandle;
        if (commonHandle.handle != nullptr) {
            return SPATIALMANAGER_OK;
        }
        commonHandle.handle = dlopen(iter.c_str(), RTLD_LAZY);
        if (commonHandle.handle == nullptr) {
            SPATIAL_LOGE(MODULE_SERVICE, "Cannot load library error = %{public}s", dlerror());
            return SPATIALMANAGER_FAILED;
        }

        SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start create pointer", __func__);
        commonHandle.create = (MsdpAlgorithmInterface *(*)()) dlsym(commonHandle.handle, "Create");
        SPATIAL_LOGI(MODULE_SERVICE, "%{public}s start destroy pointer", __func__);
        commonHandle.destroy = (void *(*)(MsdpAlgorithmInterface *))dlsym(commonHandle.handle, "Destroy");
        if (commonHandle.create == nullptr || commonHandle.destroy == nullptr) {
            SPATIAL_LOGE(MODULE_SERVICE, "%{public}s dlsym Create or Destory failed!", iter.c_str());
            dlclose(mExistAlgorithm_.handle);
            commonHandle.Clear();
            bCreate = false;
            return SPATIALMANAGER_FAILED;
        }

        if (bCreate) {
            commonHandle.pAlgorithm = commonHandle.create();
            if (commonHandle.pAlgorithm == nullptr) {
                return SPATIALMANAGER_FAILED;
            }
            MsdpAlgorithmCapability capality = commonHandle.pAlgorithm->GetCapability();
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s describe = %{public}d", __func__, capality.type);
            mServiceDllMap_.insert(std::make_pair(capality.type, iter));
            bCreate = false;
        }

        if (commonHandle.pAlgorithm != nullptr) {
            commonHandle.destroy(commonHandle.pAlgorithm);
            commonHandle.pAlgorithm = nullptr;
        }

        if (!bCreate) {
            dlclose(commonHandle.handle);
            commonHandle.Clear();
            bCreate = true;
        }
    }
    return SPATIALMANAGER_OK;
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s return", __func__);
}

int32_t SpatialAlgorithmHandle::InstallAlllib(bool bCreate)
{
    int32_t ret = SPATIALMANAGER_FAILED;
    ret = CheckAndEnforceService(AlgorithmType::DIRECTION);
    if (ret != SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s load direction algorithm library fail", __func__);
        return SPATIALMANAGER_FAILED;
    }
    ret = CheckAndEnforceService(AlgorithmType::DISTANCE);
    if (ret != SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s load distance algorithm library fail", __func__);
        return SPATIALMANAGER_FAILED;
    }
    ret = CheckAndEnforceService(AlgorithmType::ANGLE);
    if (ret != SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s load angle algorithm library fail", __func__);
        return SPATIALMANAGER_FAILED;
    }
    ret = CheckAndEnforceService(AlgorithmType::INNEROUTER);
    if (ret != SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s load innerouter ection algorithm library fail", __func__);
        return SPATIALMANAGER_FAILED;
    }
    ret = CheckAndEnforceService(AlgorithmType::EXIST);
    if (ret != SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s load exist algorithm library fail", __func__);
        return SPATIALMANAGER_FAILED;
    }
    ret = CheckAndEnforceService(AlgorithmType::COMMON);
    if (ret != SPATIALMANAGER_OK) {
        SPATIAL_LOGE(MODULE_SERVICE, "%{public}s load common algorithm library fail", __func__);
        return SPATIALMANAGER_FAILED;
    }
    return SPATIALMANAGER_OK;
}

void SpatialAlgorithmHandle::UninstallAllLib()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    UnloadDirectionLib(false);
    UnloadDistanceLib(false);
    UnloadInnerouterLib(false);
    UnloadExistLib(false);
    UnloadAngleLib(false);
    UnloadCommonLib(false);
    return;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetDirectionInst()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mDirectionAlgorithm_.handle == nullptr) {
        return nullptr;
    }
    if (mDirectionAlgorithm_.pAlgorithm == nullptr) {
        std::unique_lock<std::mutex> lock(mMutex_);
        SPATIAL_LOGI(MODULE_SERVICE, "%{public}s mDirectionAlgorithm_", __func__);
        if (mDirectionAlgorithm_.pAlgorithm == nullptr) {
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s Get mAlgorithm.pAlgorithm", __func__);
            mDirectionAlgorithm_.pAlgorithm = mDirectionAlgorithm_.create();
        }
    }
    return mDirectionAlgorithm_.pAlgorithm;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetDistanceInst()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mDistanceAlgorithm_.handle == nullptr) {
        return nullptr;
    }
    if (mDistanceAlgorithm_.pAlgorithm == nullptr) {
        std::unique_lock<std::mutex> lock(mMutex_);
        if (mDistanceAlgorithm_.pAlgorithm == nullptr) {
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s Get mAlgorithm.pAlgorithm", __func__);
            mDistanceAlgorithm_.pAlgorithm = mDistanceAlgorithm_.create();
        }
    }
    return mDistanceAlgorithm_.pAlgorithm;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetAngleInst()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mAngleAlgorithm_.handle == nullptr) {
        return nullptr;
    }
    if (mAngleAlgorithm_.pAlgorithm == nullptr) {
        std::unique_lock<std::mutex> lock(mMutex_);
        if (mAngleAlgorithm_.pAlgorithm == nullptr) {
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s Get mAlgorithm.pAlgorithm", __func__);
            mAngleAlgorithm_.pAlgorithm = mAngleAlgorithm_.create();
        }
    }
    return mAngleAlgorithm_.pAlgorithm;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetInnerouterInst()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mIoAlgorithm_.handle == nullptr) {
        return nullptr;
    }
    if (mIoAlgorithm_.pAlgorithm == nullptr) {
        std::unique_lock<std::mutex> lock(mMutex_);
        if (mIoAlgorithm_.pAlgorithm == nullptr) {
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s Get mAlgorithm.pAlgorithm", __func__);
            mIoAlgorithm_.pAlgorithm = mIoAlgorithm_.create();
        }
    }
    return mIoAlgorithm_.pAlgorithm;
}

MsdpAlgorithmInterface *SpatialAlgorithmHandle::GetExistInst()
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (mExistAlgorithm_.handle == nullptr) {
        return nullptr;
    }
    if (mExistAlgorithm_.pAlgorithm == nullptr) {
        std::unique_lock<std::mutex> lock(mMutex_);
        if (mExistAlgorithm_.pAlgorithm == nullptr) {
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s Get mAlgorithm.pAlgorithm", __func__);
            mExistAlgorithm_.pAlgorithm = mExistAlgorithm_.create();
        }
    }
    return mExistAlgorithm_.pAlgorithm;
}

void SpatialAlgorithmHandle::GetLiblaryFiles(std::string path, std::vector<std::string> &files)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter frist", __func__);
    DIR *dir;
    struct dirent *ptr;
    if ((dir = opendir(path.c_str())) == NULL) {
        perror("Open dir error...");
        return;
    }
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter second", __func__);
    while ((ptr = readdir(dir)) != NULL) {
        if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
            continue;
        } else if (ptr->d_type == DT_REG) {
            std::string strFile = ptr->d_name;
            SPATIAL_LOGI(MODULE_SERVICE, "%{public}s strFile = %{public}s", __func__, strFile.c_str());
            files.push_back(strFile);
        } else {
            continue;
        }
    }
    closedir(dir);
}

void SpatialAlgorithmHandle::RegexSearch(std::string sourceString, std::regex regexString, std::smatch& result)
{
    SPATIAL_LOGI(MODULE_SERVICE, "%{public}s enter", __func__);
    if (regex_search(sourceString, result, regexString)) {
        std::string outPut = result.str();
        SPATIAL_LOGI(MODULE_SERVICE, "%{public}s result = %{public}s", __func__, outPut.c_str());
        algorithmLibList_.push_back(outPut);
    }
}
} // namespace Msdp
} // namespace OHOS